package net.gdface.service.cassdk;

import java.util.ArrayList;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;

import net.gdface.service.sdk.FaceApiServiceConstants;

/**
 * maven 插件<br>
 * 执行cassdk-service服务启动,等同于执行{@link net.gdface.service.cassdk.WrapperMain#main(String[])}
 * 
 * @author guyadong
 *
 */
@Mojo(name = "run", requiresProject = false)
public class WrapperRunMojo extends AbstractMojo implements FaceApiServiceConstants{
	/**
	 * Set this to true to allow Maven to continue to execute after invoking the
	 * run goal.
	 *
	 */
	@Parameter(property = "maven.service.fork", defaultValue = "false")
	private boolean fork;
	/**
	 * CASSDK服务端口号<br>
	 * CASSDK service port number,default value: 26413
	 */
	@Parameter(property="maven.thrift.servicePort")
	private int servicePort = DEFAULT_PORT;
	/**
	 * 工作线程数量<br>
	 * work thread number,default: count of available processors
	 */
	@Parameter(property="maven.thrift.workThreads")
	private int workThreads = Runtime.getRuntime().availableProcessors();
	/**
	 * 连接上限<br>
	 * an upper bound on the number of concurrent connections the server will accept.default:32
	 */
	@Parameter(property="maven.thrift.connectionLimit")
	private int connectionLimit = DEFAULT_CONNECTION_LIMIT;
	/**
	 * 空闲连接超时(秒)<br>
	 * Sets a timeout period between receiving requests from a client connection. 
	 * If the timeout is exceeded (no complete requests have arrived from the client within the timeout), 
	 * the server will disconnect the idle client.default: 60s
	 */
	@Parameter(property="maven.thrift.idleConnectionTimeout")
	private int idleConnectionTimeout = DEFAULT_IDLE_TIMEOUT;
	public WrapperRunMojo() {
	}

	@Override
	public void execute() throws MojoExecutionException, MojoFailureException {
		try{
			WrapperMain.main(makeArgs());
		}catch(Exception e){
			throw new MojoExecutionException(e.getMessage(),e);
		}
		if (!fork) {
			waitIndefinitely();
		}
	}
	protected String[] makeArgs(){
		ArrayList<String> list = new ArrayList<String>(16);
		list.add("--" + SERVICE_PORT_OPTION_LONG);
		list.add(Integer.toString(servicePort));
		list.add("--" + WORK_THREADS_OPTION_LONG);
		list.add(Integer.toString(workThreads));
		list.add("--" + CONNECTION_LIMIT_OPTION_LONG);
		list.add(Integer.toString(connectionLimit));
		list.add("--" + IDLE_CONNECTION_TIMEOUT_OPTION_LONG);
		list.add(Integer.toString(idleConnectionTimeout));
		return list.toArray(new String[list.size()]);
	}
	/**
	 * Causes the current thread to wait indefinitely. This method does not
	 * return.
	 */
	private void waitIndefinitely() {
		Object lock = new Object();
		synchronized (lock) {
			try {
				lock.wait();
			} catch (InterruptedException e) {
				getLog().warn("RunMojo.interrupted", e);
			}
		}
	}
}
